""" Generic Config object supports save/load """

from S3D import TabSize
import re

class Config:
    def save(self, filename = None):
        res = ""

        for k in dir(self):
            if k.startswith('_'):
                continue

            v = getattr(self, k)
            if hasattr(v, "__call__"):
                 continue

            res += self.buildVar(k, v)

        if filename is None:
            return res

        with open(filename, 'w') as f:
            f.write(res)

    def buildVar(self, key, value, tab = 0):
        offset = ' ' * TabSize * tab

        return '%s%s = %s\n' % (offset, key, self.buildValue(value))

    def buildValue(self, value, tab = 0):
        if isinstance(value, (int, float, str)):
            res = value
            if isinstance(res, str):
                if re.search(r'[\\"\n]', res):
                    res = 'r"""%s"""' % res
                else:
                    res = '"%s"' % res
            else:
                res = str(value)

            return res

        if isinstance(value, (list, tuple)):
            if isinstance(value, list):
                LB, RB = '[', ']'
            else:
                LB, RB = '(', ')'

            hasSubLists = False
            for p in value:
                if isinstance(p, (list, tuple)):
                    hasSubLists = True
                    break

            if not hasSubLists:
                res = LB + ' '
                for index in range(len(value)):
                    res += self.buildValue(value[index])
                    if index + 1 < len(value):
                        res += ', '
                res += ' ' + RB
                return res

            res = LB + '\n'

            for v in value:
                rrr = self.buildValue(v, tab + 1)
                res += "%s%s,\n" % (' ' * (tab + 1) * TabSize, rrr)

            res += '%s%s' % (' ' * tab * TabSize, RB)
            return res

        if isinstance(value, dict):
            if len(value) == 0:
                return "{}"

            res = '{\n'

            for k in value.keys():
                res += '%s%s: ' % (' ' * (tab + 1) * TabSize, self.buildValue(k, tab + 1))
                res += self.buildValue(value[k], tab + 1)
                res += ',\n'

            res += '%s}' % (' ' * tab * TabSize)

            return res

        raise Exception("Unknown variable type: %s" % type(value))

    def load(self, filename = None, text = None, glob = None):
        if not filename is None:
            with open(filename, 'r') as f:
                text = f.read()

        params = {}

        if glob is None:
            glob = globals()

        exec(text, glob, params)

        for k in params.keys():
            setattr(self, k, params[k])
